class  BiliRankingMaker < VegasVideoMaker
    attr_accessor :vt, :pa, :ut, :ops #:ut => usual_time
    alias :vvmtime :vt
    alias :vvmtime= :vt= 

    TIME_30 = VegasVideoTime.ns(1)
    TIME_25 = VegasVideoTime.nl(25)
    TIME_20 = VegasVideoTime.nl(20)
    TIME_15 = VegasVideoTime.nl(15)
    TIME_10 = VegasVideoTime.nl(10)
    TIME_5 = VegasVideoTime.nl(5)

    VIDEO_BR = {:fade_in_length => TIME_20, :fade_out_length => TIME_20,
                :x => -4, :y => -4, :center_x => '252', :center_y => '188'}
    PIC_RANKING = {:contain_fade => 'true'}
    VIDEO_ACRE = {:fade_in_length => TIME_20, :fade_out_length => TIME_20,
                  :x => -5, :y => -5, :center_x => '251', :center_y => '187'}
    VIDEO_PICKUP = {:fade_in_length => TIME_20, :fade_out_length => TIME_20,
                  :x => -3, :y => -3, :center_x => '249', :center_y => '185'}
    
    def self.create h
      vvm = self.new()
      doc = REXML::Document.new("<?xml version=\"1.0\"?><Vegas/>")
      vegas = doc.root
      project = vegas.add_element "Project"
      project.add_element "MediaPool"
      project.add_element "Tracks"
      vvm.project = project
      vvm.pa = h[:path] || h[:pa]
      vvm.pa += '\\' unless vvm.pa.last == '\\' || vvm.pa.last == '/'
      vvm.ops = h[:ops] || YAML.load(open(File.join(%[#{vvm.pa}script/options.yml])))
      vvm.ut = {:fade_usual => h[:fade_usual] || TIME_20,
                       :fade_quick => h[:fade_quick] || TIME_10,
                       :video_pickup => h[:video_pickup] || VegasVideoTime.ns(30),
                       :video_usual => h[:video_usual] || VegasVideoTime.ns(20),
                       :video_quick => h[:video_quick] || VegasVideoTime.ns(15),
                       :video_short => h[:video_short] || VegasVideoTime.ns(10),
                       :pic_list => h[:pic_list] || VegasVideoTime.new(0, 0, 7, 25),
                       :pic_default => h[:pic_default] || VegasVideoTime.new(0, 0, 5),
                       :pic_title => h[:pic_title] || VegasVideoTime.new(0, 0, 3) 
              }
      vvm.vvmtime = VegasVideoTime.new
      #track
      #video_track 5   主要图片、扩展
      #video_track 4    背景
      #video_track 3   预览框架
      #video_track 2    视频备用
      #video_track 1   右下logo
      #video_track 0   预览、全屏预览
      #audio_track 1   通用
      #audio_track 0  备用
      vvm.add_track 6
      vvm.add_track 2, 'AudioTrack'
      #=======
      yield vvm
      doc
    end

    def public_pa;  %[#{pa}..\\public\\]; end
    def list1_pa;  %[#{pa}2_list1\\]; end
    def list2_pa;  %[#{pa}3_list2\\]; end
    def video_pa;  %[#{pa}video\\]; end
    def op_pa;  %[#{pa}1_op\\]; end
    def ed_pa;  %[#{pa}4_ed\\]; end
    def pic_pa;  %[#{pa}pic\\]; end
    def pickup_pa;  %[#{pa}pickup\\]; end

    def black_before
      @vt = VegasVideoTime.new 0,7
      self
    end
    
    def op
      add_video @vt, 4,{:file => "title.png", :pa => op_pa, :index => 4,
                             :fade_in_length => TIME_15}
      start_time = @vt.clone
      add_video @vt, VegasVideoTime.new(0, 0, 3, 16),{:file => "warning.png", :pa => public_pa, :index => 5}
      add_video @vt, VegasVideoTime.new(0, 0, 6),{:file => "1.png", :pa => op_pa, :index => 5,
                                           :fade_out_length => TIME_20, :contain_fade => 'true'}
      add_video start_time, @vt - start_time,{:file => "blank.png", :pa => public_pa, :index => 4}
      self
    end

    def ed
      add_video @vt, ut[:pic_default],{:file => "addr.png", :pa => ed_pa, :index => 5,
                             :fade_in_length => TIME_30, :contain_fade => 'none'}
      add_video @vt + ut[:pic_default], ut[:pic_default],{:file => "addr2.png", :pa => ed_pa, :index => 5,
                              :fade_out_length => TIME_30, :contain_fade => 'none'}
      add_video @vt + ut[:pic_default] + ut[:pic_default], ut[:pic_default],{:file => "ed.png", :pa => ed_pa, :index => 5,
                             :fade_in_length => TIME_30, :fade_out_length => TIME_30, :contain_fade => 'none'}
      add_video @vt, ut[:pic_default] + ut[:pic_default] + ut[:pic_default],{:file => "ed.png", :pa => public_pa, :index => 4,
                             :fade_in_length => TIME_30, :fade_out_length => TIME_30}
      self
    end

    #options = {:index => {:length => "vvmtime", :offset => "vvmtime" ,:m,:h},
    #                :length => VIDEO_USUAL}
    #                :num => 4..30
    def list1 num, options = ops[:rank]
      num.to_a.reverse.each_with_index do |i, index|
        options[i] = opt( options[i], options[:length] ||  ut[:video_usual])
        unless index.zero? || options[i][:no_pause]
          add_audio @vt, TIME_30, {:file => 'av2313.mp3', :pa => public_pa}
          if File.exist?(%[#{list1_pa}\\top#{i}_p.png])
            add_video @vt, TIME_30,{:file => "top#{i}_p.png", :pa => list1_pa, :index => 2}
          else
            add_video @vt, TIME_30,{:file => 'change.png', :pa => public_pa, :index => 2}
          end
        end
        add_video @vt, options[i][:length],
                  {:index => 3, :file => "top#{i}.png", :pa => list1_pa, :contain_fade => 'none',
                   :fade_out_length => ( index + 1 == num.to_a.size ?  ut[:fade_usual] : nil) }
        if options[i][:m]
          add_video @vt, options[i][:length],
                    {:index => 5, :file => "model_m.png", :pa => public_pa, :contain_fade => 'none',
                     :fade_out_length => ( index + 1 == num.to_a.size ?  ut[:fade_usual] : nil) }
        end
        if options[i][:h]
          add_video @vt, options[i][:length],
                    {:index => 5, :file => "model_h.png", :pa => public_pa, :contain_fade => 'none',
                     :fade_out_length => ( index + 1 == num.to_a.size ?  ut[:fade_usual] : nil) }
        end
        if options[i][:p]
          add_video @vt, options[i][:length],
                    {:index => 5, :file => "model_p.png", :pa => public_pa, :contain_fade => 'none',
                     :fade_out_length => ( index + 1 == num.to_a.size ?  ut[:fade_usual] : nil) }
        end
        if options[i][:sound_only]
          add_audio @vt, options[i][:length], {:file => "top#{i}.mp3", :pa => list1_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil), :time_go => 'true'}
        elsif options[i][:image_only]
          add_video @vt, options[i][:length], {:file => "top#{i}.avi", :pa => list1_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil)}.merge(VIDEO_BR)
        else
          add_video_and_audio @vt, options[i][:length], {:index => 0, :file => "top#{i}.avi", :pa => list1_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil), :contain_fade => 'true'}.merge(VIDEO_BR)
        end
      end
      self
    end

     #options = {:index => {:length => "vvmtime", :short => "vvmtime", :offset => "vvmtime" , :m, :h},
    #                :length => VVMTime.new(0, 0, 30), :short => VVMTime.new(0, 0, 15)}
    #                :num => 1..3
    def list3 num = 1..3, options = ops[:rank]
      num.to_a.reverse.each do |i|
        options[i] = opt( options[i], options[:length] || VegasVideoTime.new(0, 0, 30), :short => options[:short] || VegasVideoTime.new(0, 0, 15) )
        start_time = @vt.clone
        add_video start_time, 5,
                  {:index => 4, :file => "top#{i}_.png", :pa => list1_pa, :contain_fade => 'none', :fade_in_length => TIME_30}
        add_video @vt, 5, {:index => 3, :file => "blank.png", :pa => public_pa}
        add_video @vt, options[i][:short] -  VegasVideoTime.new(0, 0, 5), {:index => 3, :file => "top#{i}.png", :pa => list1_pa, :contain_fade => 'none'}
        if options[i][:m]
          add_video @vt, options[i][:short] -  VegasVideoTime.new(0, 0, 5), {:index => 5, :file => "model_m.png", :pa => public_pa, :contain_fade => 'none'}
          add_video @vt + options[i][:short] -  VegasVideoTime.new(0, 0, 5), options[i][:length] - options[i][:short],
                    {:index => 5, :file => "model_m_b.png", :pa => public_pa, :contain_fade => 'none'}
        end
        if options[i][:h]
          add_video @vt, options[i][:short] -  VegasVideoTime.new(0, 0, 5), {:index => 5, :file => "model_h.png", :pa => public_pa, :contain_fade => 'none'}
        end
        add_video start_time, options[i][:short],
                  {:index => 2, :file => "top#{i}.avi", :offset => options[i][:offset], :pa => list1_pa, :contain_fade => 'none'
                  }.merge(VIDEO_BR).merge(:fade_out_length => nil)
        add_video_and_audio start_time, options[i][:length],
                            {:index => 0, :file => "top#{i}_.avi", :pa => list1_pa, :offset => options[i][:offset],
                             :fade_in_length => TIME_30, :fade_out_length => TIME_30, :contain_fade => 'true', :pic_fade => 'only'}
        start_time.add(TIME_20)
        @vt = start_time.clone
      end
      self
    end
    
    #options = {:length => ut[:pic_list]}, :num => 1..30
    def list2 num = 1..30, options = {} 
      list_start_time = @vt.clone
      @vt.add VegasVideoTime.new(0,0,0,15)
      num.each do |i|
        add_video @vt, options[:length] ||  ut[:pic_list],
        {:index => 4, :file => "#{'0'*(3-i.to_s.size)}#{i}.png", :pa => list2_pa}.merge(PIC_RANKING)
      end
      add_video list_start_time, @vt - list_start_time + 2,
        {:index => 3, :file => "blank.png", :pa => public_pa}
      @vt.add VegasVideoTime.new(0, 0, 0, 20)
      self
    end

    #options = {:index => {:length => PIC_DEFAULT},
    #                :length => PIC_DEFAULT}
    def pics name, range, options = {}
      start_time = @vt.clone
      range.each do |r|
        options[r] = opt( options[r], options[:length] || ut[:pic_default] )
        add_video @vt, options[r][:length],{:file => "#{name}_#{r}.png", :pa => pic_pa, :index => 5,
                               :fade_in_length => TIME_20, :fade_out_length => TIME_20,
                               :contain_fade => (r == range.max ? 'true' : nil)}.merge(options).merge(options[r])
      end
      add_video start_time, @vt - start_time,{:file => "blank.png", :pa => public_pa, :index => 4}
      self
    end

    #options = {:index => {:length => ut[:video_pickup],
    #                :length => ut[:video_pickup]}
    def pickup num=1..ops[:pickup_count], options = ops[:pickup], name='pickup'
      num.each_with_index do |i, index|
        options[i] = opt( options[i], options[:length] || ut[:video_pickup] )
        if name=='pickup'
          add_video @vt + VegasVideoTime.ns(15), options[i][:length] - VegasVideoTime.ns(15),
                  {:index => 5, :file => "#{name}_#{i}_r.png", :pa => pickup_pa, :contain_fade => 'none',
                   :fade_in_type => 'Sony Linear Wipe', :fade_in_length => TIME_30,
                   :fade_out_length => ( index + 1 == num.to_a.size ? ut[:fade_usual] : nil) }
        end
        add_video @vt, options[i][:length],
                  {:index => 3, :file => "#{name}_#{i}.png", :pa => pickup_pa, :contain_fade => 'none',
                   :fade_out_length => ( index + 1 == num.to_a.size ? ut[:fade_usual] : nil) }
        if options[i][:sound_only]
          add_audio @vt, options[i][:length], {:file => "#{name}_#{i}.mp3", :pa => pickup_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil), :time_go => 'true'}
        elsif options[i][:image_only]
          add_video @vt, options[i][:length], {:file => "#{name}_#{i}.avi", :pa => pickup_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil)}.merge(VIDEO_PICKUP)
        else
          add_video_and_audio @vt, options[i][:length], {:index => 0, :file => "#{name}_#{i}.avi", :pa => pickup_pa, :offset => options[i][:offset],
                                :pic_fade => ( index + 1 == num.to_a.size ? "only" : nil), :contain_fade => 'true'}.merge(VIDEO_PICKUP)
        end
      end
      self
    end   

    def tag num = 1..3, options = ops[:tag]
       pickup num, options, 'tag'
    end

    def history num=1..5, options=ops[:history] 
       pickup num, options.merge({:length => ut[:video_quick] }), 'history'
    end

    def title index, has_audio = false, length = ut[:pic_title] , options = {}
      add_audio @vt, 2, {:file => 'bilibili-mubox.wav', :pa => public_pa} if has_audio
      add_video @vt, length || ut[:pic_title] ,{:file => "_#{index}.png", :pa => pic_pa, :index => 5,
                             :fade_in_length => TIME_20}.merge(options)
      self
    end

    def music file, length, options = {}
       add_audio options[:start_time] || @vt, length, {:file => file, :pa => public_pa, :fade_out_length => TIME_30}.merge(options)
      self
    end

    def logo
      add_video VegasVideoTime.new, @vt, {:index => 1, :file => "logo.png", :pa => public_pa, :contain_fade => 'none'}
      self
    end

    def play_bgm bgm_file
      bgm_time = @vt.clone
      yield
      music bgm_file, @vt - bgm_time - 1, :start_time => bgm_time
    end

    def ed_bgm
      ops[:ed_bgm] ||= {}
      bgm_time = @vt.clone
      bgm_time.add ops[:ed_bgm][:offset] if ops[:ed_bgm][:offset]
      yield ops[:ed_bgm][:end].to_i + ops[:ed_bgm][:length].to_i + ops[:ed_bgm][:offset].to_i
      music ops[:ed_bgm][:file_name] || "ed", @vt - bgm_time, :start_time => bgm_time, :pa => ed_pa
    end
    
    def opt i, default_time, options = {}
        i ||= {}
        i[:length] ||= default_time
        i[:short] ||= options[:short] if options[:short]
        i[:length] = VegasVideoTime.ns(i[:length]) if i[:length].is_a?(Integer)
        i[:offset] = VegasVideoTime.ns(i[:offset]) if i[:offset].is_a?(Integer)
        i[:short] = VegasVideoTime.ns(i[:short]) if i[:short].is_a?(Integer)
        i
    end
    private :opt
end